package com.buaa.utils;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Repository;

/**
 * Title: 数据持久层工具类
 * Description: 
 * Company: BUAA
 *
 * @author 伟宏 
 * @date 2017年1月15日
 */
@Repository("hibernateUtil")
public class HibernateUtil {

	@Autowired
	private HibernateTemplate template;

	private SessionFactory sessionFactory = null;

	private SessionFactory openSessionFactory() {
		if (sessionFactory == null) {
			sessionFactory = template.getSessionFactory();
		}
		return sessionFactory;
	}

	// public SessionFactory getSessionFactory() {
	// return template.getSessionFactory();
	// }

	/**
	 * 释放session
	 * 
	 * @param session
	 */
	private void releaseSession(Session session) {
		if (session.close() != null)
			throw new RuntimeException("attention,session close error.....");
	}

	/**
	 * 保存对象
	 * 
	 * @param object
	 * 			对象
	 * @return 
	 * 		true  : 成功<br/>
	 * 		false : 失败
	 */
	public boolean save(Object object) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.getCurrentSession();
			session.save(object);
			releaseSession(session);
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 删除对象
	 * 
	 * @param obj
	 * @return
	 * 	  	true  : 成功<br/>
	 * 		false : 失败
	 */
	public boolean delete(Object obj) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.getCurrentSession();
			session.delete(obj);
			releaseSession(session);
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 修改对象
	 * 
	 * @param obj
	 * @return
	 * 	    true  : 成功<br/>
	 * 		false : 失败
	 */
	public boolean update(Object obj) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.getCurrentSession();
			session.update(obj);
			releaseSession(session);
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 通过参数构造Query对象
	 * 
	 * @param query
	 * @param argsMap
	 */
	private void constructorQuery(Query query, Map<String, Object> argsMap) {
		if (argsMap == null || argsMap.size() == 0) {
			return;
		} else {
			for (Entry<String, Object> args : argsMap.entrySet()) {
				query.setParameter(args.getKey(), args.getValue());
			}
		}
	}

	/**
	 * 通过HQL查询对象
	 * 
	 * @param hql : String hql语句
	 * @param argsMap : Map(String, Object) 参数列表
	 * @param cacheable : Boolean 是否使用二级缓存
	 * @return
	 * 		查询成功 ：Object <br/>
	 * 		查询失败 : null
	 */
	@SuppressWarnings("unchecked")
	public Object findByHQL(String hql, Map<String, Object> argsMap, Boolean cacheable) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.openSession();
			Query query = session.createQuery(hql).setCacheable(cacheable);
			constructorQuery(query, argsMap);
			List<Object> list = query.list();
			releaseSession(session);
			if (list != null && list.size() != 0)
				return list.get(0);
			return null;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过SQL查询对象
	 * 
	 * @param sql
	 * @param argsMap
	 * @return
	 * 		查询成功 ：Object
	 * 		查询失败 : null
	 */
	@SuppressWarnings("unchecked")
	public Object findBySQL(String sql, Map<String, Object> argsMap) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.openSession();
			SQLQuery query = session.createSQLQuery(sql);
			constructorQuery(query, argsMap);
			List<Object> list = query.list();
			releaseSession(session);
			if (list != null && list.size() != 0)
				return list.get(0);
			return null;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过类、id查询对象
	 * 
	 * @param clasz
	 * @param code
	 * @return
	 * 		成功 ： object
	 * 		失败 ： null
	 */
	@SuppressWarnings("rawtypes") 
	public <T> Object get(Class clazz, T code) {   // 泛型
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.openSession();
			Object object = session.get(clazz, (Serializable) code);
			releaseSession(session);
			return object;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过HQL查询对象
	 * 
	 * @param hql : String hql查询语句
	 * @param argsMap ：Map(String,Object) 查询参数
	 * @param cacheable ： Boolean 是否缓存
	 * @return
	 * 	           查询成功 ：List
	 * 		查询失败 : null
	 */

	@SuppressWarnings("rawtypes")
	public List findAllByHQL(String hql, Map<String, Object> argsMap, Boolean cacheable) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.openSession();
			Query query = session.createQuery(hql).setCacheable(cacheable);
			constructorQuery(query, argsMap);
			List list = query.list();
			releaseSession(session);
			if (list != null && list.size() != 0)
				return list;
			return null;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 通过SQL查询对象
	 * 
	 * @param sql
	 * @param argsMap
	 * @return
	 * 	           查询成功 ：List
	 * 		查询失败 : null
	 */
	@SuppressWarnings("rawtypes")
	public List findAllBySQL(String sql, Map<String, Object> argsMap) {
		try {
			sessionFactory = openSessionFactory();
			Session session = sessionFactory.openSession();
			SQLQuery query = session.createSQLQuery(sql);
			constructorQuery(query, argsMap);
			//System.out.println(sql);
			List list = query.list();
			releaseSession(session);
			if (list != null && list.size() != 0)
				return list;
			return null;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	// // 执行sql语句
	// public List<Object> queryBySQL(String sql) {
	// Session session = getSessionFactory().openSession();
	// Query query = session.createSQLQuery(sql);
	// List<Object> list = query.list();
	// return list;
	// }
	//
	// public Object findByHQL(String str, Object[] args) {
	// try {
	// sessionFactory = openSessionFactory();
	// Session session = sessionFactory.openSession();
	// Query query = session.createQuery(str);
	//
	// constructorQuery(query, args);
	//
	// List<Object> list = query.list();
	// releaseSession(session);
	// if (!validateIfNull(list))
	// return list.get(0);
	// return null;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// public boolean save(List<?> objList1, List<?> objList2) {
	// try {
	// sessionFactory = openSessionFactory();
	// Session session = sessionFactory.getCurrentSession();
	// for (Object obj : objList1) {
	// session.save(obj);
	// }
	// for (Object obj : objList2) {
	// session.save(obj);
	// }
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return false;
	// }
	// return true;
	// }
	//
	// public boolean save(List<?> objList) {
	// try {
	// sessionFactory = openSessionFactory();
	// Session session = sessionFactory.getCurrentSession();
	// for (Object obj : objList) {
	// session.save(obj);
	// }
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return false;
	// }
	// return true;
	// }
	//
	// /**
	// * 通过参数获取对象（基于hibernate4对占位符的新写法）
	// * @param sqlQuery
	// * @param argsList
	// * @return
	// */
	// public Object findByHQL(String sqlQuery, List<String[]> argsList) {
	// Session session = getSessionFactory().openSession();
	// Query query = session.createQuery(sqlQuery);
	//
	// constructorQuery(query, argsList);
	//
	// List<Object> list = (List<Object>) query.list();
	// if (!validateIfNull(list)) {
	// releaseSession(session);
	// return list.get(0);
	// }
	// return null;
	// }
	//
	// /**
	// * 获取结果的集合
	// * @param sqlQuery
	// * @param args
	// * @return
	// */
	// public List<Object> findAllByQuery(String sqlQuery, List<Object[]> args)
	// {
	// Session session = getSessionFactory().openSession();
	// SQLQuery query = session.createSQLQuery(sqlQuery);
	// constructor(query, args);
	// List<Object> resultList = query.list();
	// releaseSession(session);
	// return resultList;
	// }
	//
	// /**
	// * 通过参数获取对象列表（基于hibernate4对占位符的新写法）
	// * @param sqlQuery
	// * @param argsList
	// * @return
	// */
	// public List<Object> findListByParamAndHQL(String sqlQuery, List<String[]>
	// argsList) {
	// Session session = getSessionFactory().openSession();
	// Query query = session.createQuery(sqlQuery);
	//
	// constructorQuery(query, argsList);
	// List<Object> list = query.list();
	// if (!validateIfNull(list))
	// return list;
	// return null;
	// }
	//
	// /**
	// * 通过sql语句获取对象集合
	// * @param sql
	// * @return
	// */
	// public List<Object> findBySQL(String sql, Object[] args) {
	// Session session = openSessionFactory().openSession();
	// SQLQuery sqlQuery = session.createSQLQuery(sql);
	//
	// constructorQuery(sqlQuery, args);
	//
	// List<Object> list = sqlQuery.list();
	// if (validateIfNull(list))
	// return null;
	// releaseSession(session);
	// return list;
	// }
	//
	// /**
	// * 查询所有符合条件的数据
	// * @param str SQL或者HQL语句
	// * @return
	// */
	// public List<Object> findAll(String str, Object[] args) {
	// try {
	// sessionFactory = openSessionFactory();
	// Session session = sessionFactory.openSession();
	// Query query = session.createQuery(str);
	//
	// constructorQuery(query, args); // 构造Query
	//
	// @SuppressWarnings("rawtypes")
	// List list = query.list();
	// releaseSession(session);
	// if (!validateIfNull(list))
	// return list;
	// return null;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// /**
	// * 查询所有符合条件的数据
	// * @param sqlQuery SQL语句
	// * @param args 参数列表
	// * @return
	// */
	// public List<Object> findAllBySQL(String sqlQuery, Object[] args) {
	// try {
	// sessionFactory = openSessionFactory();
	// Session session = sessionFactory.openSession();
	// SQLQuery query = session.createSQLQuery(sqlQuery);
	//
	// constructorQuery(query, args); // 构造Query
	//
	// @SuppressWarnings("rawtypes")
	// List list = query.list();
	// releaseSession(session);
	// if (!validateIfNull(list))
	// return list;
	// return null;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// /**
	// * 分页
	// * @param string
	// * @param args
	// * @return
	// */
	// public List<Object> pageTurn(String string, Object[] args, int startRow,
	// int pageSize) {
	// try {
	// Session session = openSession();
	// Query query = session.createQuery(string);
	//
	// setPageInfo(query, args, startRow, pageSize);
	//
	// List<Object> resultList = query.list();
	// releaseSession(session);
	// return resultList;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// /**
	// * 使用sql语句的分页
	// * @param string
	// * @param startRow
	// * @param pageSize
	// * @return
	// */
	// public List<Object> pageTurnBySQL(String string, int startRow, int
	// pageSize) {
	// try {
	// Session session = openSession();
	//
	// Query query = session.createSQLQuery(string);
	// query.setFirstResult(startRow);
	// query.setMaxResults(pageSize);
	// List<Object> resultList = query.list();
	//
	// releaseSession(session);
	// return resultList;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// /**
	// * 使用sql语句的分页
	// * @param string
	// * @return
	// */
	// public List<Object> pageTurnBySQL(String string) {
	// try {
	// Session session = openSession();
	//
	// Query query = session.createSQLQuery(string);
	// List<Object> resultList = query.list();
	//
	// releaseSession(session);
	// return resultList;
	// } catch (HibernateException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }
	//
	// /**
	// * 开启session
	// * @return
	// */
	// private Session openSession() {
	// return openSessionFactory().openSession();
	// }
	//
	// /**
	// * 设置分页
	// * @param query
	// * @param startRows
	// * @param size
	// * @return
	// */
	// private Query setPageInfo(Query query, Object[] args, int startRows, int
	// size) {
	// constructorQuery(query, args);
	// query.setFirstResult(startRows);
	// query.setMaxResults(size);
	// return query;
	// }
	//
	// /**
	// * 构造带参数的Query
	// * @param query
	// * @param args 参数数组
	// * @return
	// */
	// private Query constructorQuery(Query query, Object[] args) {
	//
	// if (args == null || args.length == 0)
	// return query;
	// else {
	// for (int i = 0; i < args.length; i++) {
	// query.setParameter(i, args[i]);
	// }
	// }
	// return query;
	// }
	//
	// /**
	// * 基于hibernate4新占位符写法，构造带参数的query
	// * @param query
	// * @param argsList
	// * @return
	// */
	// private Query constructorQuery(Query query, List<String[]> argsList) {
	// if (argsList == null || argsList.size() == 0) {
	// return query;
	// } else {
	// for (String[] args : argsList) {
	// query.setParameter(args[0], args[1]);
	// }
	// return query;
	// }
	// }
	//
	// /**
	// * 基于hibernate4新的占位符写法，构造改参数的query
	// * @param query
	// * @param args
	// * @return
	// */
	// private Query constructor(Query query, List<Object[]> args) {
	// if (args == null || args.size() == 0) {
	// return query;
	// } else {
	// for (Object[] objects : args) {
	// query.setParameter(objects[0].toString(), objects[1]);
	// }
	// return query;
	// }
	// }
	//
	// /**
	// * 验证list是否为空
	// *
	// * @param list
	// * @return
	// * true : list为空<br/>
	// * false : list不为空
	// */
	// private boolean validateIfNull(List<?> list) {
	// if (list == null || list.size() == 0)
	// return true;
	// return false;
	// }

}
